<%--
  Created by IntelliJ IDEA.
  User: 您的名字
  Version: 1.0
 --%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<html>
<head>
    <title>EasyUI CRUD 示例页面</title>
    <meta charset="UTF-8" name="viewport" content="width=device-width, initial-scale=1.0">
    <base href="<%=request.getContextPath()%>/">
    <!-- 引入 EasyUI 的默认主题样式 -->
    <link rel="stylesheet" type="text/css" href="static/js/easyui/themes/bootstrap/easyui.css">
    <!-- 引入 EasyUI 的图标样式 -->
    <link rel="stylesheet" type="text/css" href="static/js/easyui/themes/icon.css">
    <!-- 引入自定义的公共CSS -->
    <link rel="stylesheet" type="text/css" href="static/css/common.css"/>
    <!-- 引入省市区的公共CSS -->
    <link rel="stylesheet" type="text/css" href="static/css/address.css"/>
    <!-- 引入 EasyUI 默认的 jQuery（无需单独引入 jQuery） -->
    <script src="static/js/easyui/jquery.min.js"></script>
    <!-- 引入 EasyUI 的核心 JS 文件 -->
    <script src="static/js/easyui/jquery.easyui.min.js"></script>
    <!-- 引入 EasyUI 的中文语言包 -->
    <script src="static/js/easyui/locale/easyui-lang-zh_CN.js"></script>
    <!-- 引入自定义的公共脚本 -->
    <script src="static/js/owner/common.js"></script>
    <!-- 引入自定义的公共脚本 -->
    <script src="static/js/owner/dataGrid.js"></script>
    <!-- 引入省市区的公共脚本 -->
    <script src="static/js/owner/address.js"></script>
    <script src="static/js/owner/city_code.js"></script>
    <!-- 引入 moment.js 库，用于处理日期和时间 -->
    <script src="static/js/owner/moment.min.js"></script>
    <!-- daterangepicker 是一个日期范围选择插件，支持选择开始和结束日期 -->
    <link rel="stylesheet" href="static/css/daterangepicker.css">
    <!-- 引入 daterangepicker 的脚本文件 -->
    <script src="static/js/owner/daterangepicker.js"></script>
</head>
<body>
<!-- 工具栏 -->
<div id="toolbar">
    <!-- 查询表单 -->
    <form id="searchForm" class="custom-search-form">
        <div class="custom-search-form__group">
            <label>所属门店:</label>
            <input class="easyui-textbox" name="storeName">
        </div>
        <div class="custom-search-form__group">
            <label>在线状态:</label>
            <input name="isOnline" class="easyui-combobox" data-options="
                valueField: 'ourId',
                textField: 'ourValue',
                data: [
                    {ourId: '0', ourValue: '在线'},
                    {ourId: '1', ourValue: '离线'}
                ],
                panelHeight: 'auto',
                editable: false,
                prompt: '请选择'
            ">
        </div>
        <div class="custom-search-form__group">
            <label>创建时间:</label>
            <input id="createTime" class="easyui-datebox daterange" name="createTime">
        </div>
        <div class="custom-search-form__actions">
            <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-search" onclick="searchData()">查询</a>
            <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-reload" onclick="resetSearch()">重置</a>
        </div>
    </form>
    <!-- 操作按钮 -->
    <div style="margin-top: 20px;margin-bottom: 10px">
        <shiro:hasPermission name="roles:add">
            <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-add" plain="true"
               onclick="newUser()">新增</a>
        </shiro:hasPermission>
        <shiro:hasPermission name="roles:update">
            <a href="javascript:void(0)" id="editBtn" class="easyui-linkbutton" iconCls="icon-edit" plain="true"
               onclick="editUser()">编辑</a>
        </shiro:hasPermission>
        <shiro:hasPermission name="roles:delete">
            <a href="javascript:void(0)" id="removeBtn" class="easyui-linkbutton" iconCls="icon-remove" plain="true"
               onclick="destroyUser()">删除</a>
        </shiro:hasPermission>
        <shiro:hasPermission name="roles:view">
            <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-save" plain="true" onclick="excelDoc('roles/export')">导出</a>
            <a href="javascript:void(0)" id="detailBtn" class="easyui-linkbutton" iconCls="icon-search" plain="true" onclick="viewDetails(``)">查看详情</a>
        </shiro:hasPermission>
        <a href="javascript:void(0)" id="refreshBtn" class="easyui-linkbutton" iconCls="icon-search" plain="true" onclick="reload()">刷新</a>
    </div>
</div>

<!-- 数据表格 -->
<table id="datagrid" class="easyui-datagrid">
    <thead>
    <tr>
        <!-- 复选框 -->
        <th data-options="field:'ck',checkbox:true"></th>
        <th data-options="field:'id',width:100">角色编号</th>
        <th data-options="field:'name',width:100">角色名称</th>
        <th data-options="field:'status',width:100">状态</th>
        <th data-options="field:'createTime',width:150,sortable:true,formatter:formatDate">创建时间</th>
    </tr>
    </thead>
</table>

<!-- 对话框，用于新增和编辑记录 -->
<div id="dlg" class="easyui-dialog custom-dlg" style="width:800px" data-options="closed:true,modal:true,border:'thin',buttons:'#dlg-buttons'">
    <form id="fm" method="post" class="custom-dlg-form" enctype="multipart/form-data" >
        <!-- 隐藏的 ID 字段 -->
        <input type="hidden" name="id">

        <div class="form-container">
            <!-- 左侧列 -->
            <div class="form-column">
                <!-- 角色名称 -->
                <div class="form-group">
                    <label>角色名称</label>
                    <input name="name" class="easyui-textbox" style="width:100%">
                </div>
                <!-- 备注 -->
                <div class="form-group">
                    <label>备注</label>
                    <input name="description" class="easyui-textbox" style="width:100%">
                </div>
            </div>

            <!-- 右侧列 -->
            <div class="form-column">
                <!-- 菜单权限 -->
                <div class="form-group">
                    <label>菜单权限</label>
                    <input name="menusId" id="comboTree" style="width:100%">
                </div>

                <!-- 操作权限 -->
                <div class="form-group">
                    <label>操作权限</label>
                    <input name="permissionsIds" id="permissionsCombo" style="width:100%">
                </div>
            </div>
        </div>
    </form>
    <!-- 对话框的按钮 -->
    <div id="dlg-buttons">
        <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-ok" onclick="saveUser()">保存</a>
        <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-cancel" onclick="javascript:$('#dlg').dialog('close')">取消</a>
    </div>
</div>

</body>
<!-- 定义页面脚本 -->
<script type="text/javascript">
let url; // 定义全局变量，保存当前操作的URL
let $comboTree = $('#comboTree');
let $datagrid = $('#datagrid');

$(function () {
    const pageConfig = {
        url: 'roles/selectRolesList', // 数据源URL
        emptyMsg: '暂无数据',     //当 DataGrid 中没有数据时，会在表格中间显示"暂无数据"的提示。
    };

    // 调用公共函数初始化 DataGrid
    initializeDataGrid(pageConfig);

    // 初始化权限控制
    initPermissionControls();
});

// 初始化权限控制
function initPermissionControls() {
    // 使用AJAX调用后端接口获取当前用户权限
    $.ajax({
        url: 'roles/getUserPermissions',
        type: 'get',
        success: function(data) {
            if (data && data.extend && data.extend.permissions) {
                let permissions = data.extend.permissions;

                // 如果没有编辑权限，禁用编辑按钮
                if (!hasPermission(permissions, 'roles:update')) {
                    $('#editBtn').linkbutton('disable');
                }

                // 如果没有删除权限，禁用删除按钮
                if (!hasPermission(permissions, 'roles:delete')) {
                    $('#removeBtn').linkbutton('disable');
                }

                // 如果没有查看权限，禁用详情按钮
                if (!hasPermission(permissions, 'roles:view')) {
                    $('#detailBtn').linkbutton('disable');
                }
            }
        },
        error: function() {
            $.messager.alert('错误', '获取用户权限失败', 'error');
        }
    });
}

// 检查是否有指定权限
function hasPermission(permissions, permissionName) {
    if (!permissions || !permissions.length) return false;
    return permissions.indexOf(permissionName) !== -1;
}

function initComboTree() {
    // 获取当前选中的角色id
    let row = $datagrid.datagrid('getSelected');
    let roleId = row ? row.id : '';

    $comboTree.combotree({
        url: 'menu/selectMenuNodeByRoleId',
        method: 'get',
        queryParams: {
            roleId: roleId
        },
        multiple: true,               // 允许多选
        checkbox: true,               // 显示复选框
        lines: false,                 // 显示连接线
        editable: false,              // 不允许编辑
        panelMaxHeight: 200,          // 固定最大高度为200px
        valueField: 'id',             // 值字段
        textField: 'text',            // 文本字段
        cascadeCheck: false,          // 取消级联选中，避免自动勾选父节点
        onlyLeafCheck: false,         // 所有节点都可以选中
        loadFilter: function (data) {
            if (data && data.extend && Array.isArray(data.extend.menus)) {
                return data.extend.menus;
            }
            return data;
        },
        onClick: function(node) {
            $comboTree.combotree('tree').tree('toggle', node.target);
        },
        onLoadSuccess: function (node, data) {
            console.log("加载成功时检查后端返回的数据: ", data);
            // 底层机制仍然是懒加载，我们只是添加了自动展开所有节点的行为
            var tree = $comboTree.combotree('tree');
            if (tree) {
                // 获取所有根节点
                var roots = tree.tree('getRoots');
                if (roots && roots.length > 0) {
                    // 遍历并展开所有根节点
                    for (var i = 0; i < roots.length; i++) {
                        // 展开根节点
                        tree.tree('expand', roots[i].target);
                        // 递归展开所有子节点
                        expandAllNodes(tree, roots[i]);
                    }
                }

                // 在节点展开后设置选中状态
                if (data && data.extend && data.extend.menus) {
                    // 延迟一点执行，确保树已完全展开
                    setTimeout(function() {
                        // 清除所有选中状态
                        var allNodes = tree.tree('getChecked', ['checked', 'indeterminate']);
                        for (var i = 0; i < allNodes.length; i++) {
                            tree.tree('uncheck', allNodes[i].target);
                        }

                        // 只选中后端返回的已授权节点
                        for (var i = 0; i < data.extend.menus.length; i++) {
                            var node = data.extend.menus[i];
                            if (node.checked) {
                                var treeNode = tree.tree('find', node.id);
                                if (treeNode) {
                                    tree.tree('check', treeNode.target);
                                }
                            }
                        }
                    }, 100);
                }
            }
        }
    });

    // 初始化权限下拉框
    initPermissionsCombo();
}

// 递归展开所有节点
function expandAllNodes(tree, node) {
    // 展开当前节点
    tree.tree('expand', node.target);

    // 获取当前节点的所有子节点
    var children = tree.tree('getChildren', node.target);
    if (children && children.length > 0) {
        // 遍历所有子节点
        for (var i = 0; i < children.length; i++) {
            // 递归展开子节点
            expandAllNodes(tree, children[i]);
        }
    }
}

// 初始化操作权限下拉框
function initPermissionsCombo() {
    $('#permissionsCombo').combotree({
        url: 'permissions/listTree',  // 树形权限列表接口
        method: 'get',
        multiple: true,           // 允许多选
        checkbox: true,           // 显示复选框
        // lines: true,              // 显示连接线
        animate: true,            // 展开/折叠动画效果
        panelHeight: 300,         // 下拉面板高度
        editable: false,          // 不允许编辑
        cascadeCheck: true,       // 级联选中
        onlyLeafCheck: false,     // 允许选择父节点
        loadFilter: function(data) {
            if (data && data.extend && data.extend.permissions) {
                return data.extend.permissions;
            }
            return [];
        },
        onLoadSuccess: function() {
            // 添加样式类
            // $(this).combotree('panel').addClass('permission-tree');

            // 如果当前是编辑模式，加载角色已有的权限
            let roleId = $('input[name="id"]').val();
            if (roleId) {
                // 加载角色已有的权限
                $.ajax({
                    url: 'permissions/getByRoleId',
                    method: 'get',
                    data: { roleId: roleId },
                    success: function(data) {
                        if (data.code === '200' && data.extend && data.extend.permissions) {
                            // 获取所有权限ID
                            let permissionIds = data.extend.permissions.map(function(item) {
                                return item.id;
                            });
                            // 设置已选权限
                            $('#permissionsCombo').combotree('setValues', permissionIds);
                        }
                    }
                });
            }
        }
    });
}

function newUser() {
    $('#dlg').dialog('open').dialog('setTitle', '新增记录').window('center'); // 打开对话框
    $('#fm').form('clear'); // 清空表单
    url = 'roles/add'; // 设置新增记录的请求URL
}

// 编辑记录
function editUser() {
    let row = $datagrid.datagrid('getSelected'); // 获取选中行
    if (row) {
        $('#dlg').dialog('open').dialog('setTitle', '编辑记录').window('center');
        $('#fm').form('load', row); // 加载选中行的数据到表单

        initComboTree();
        url = 'roles/update'; // 设置更新记录的请求URL
    } else {
        $.messager.alert('提示', '请先选择要编辑的记录！', 'info');
    }
}

function saveUser() {
    removeEmptyFields('#fm');

    if (!$('#fm').form('validate')) {
        $.messager.show({
            title: '提示',
            msg: '请检查输入项的有效性！',
            timeout: 2000, // 自动关闭时间，单位毫秒
            showType: 'slide' // 显示动画类型，如 'slide', 'fade', 'show'
        });
    }

    let formData = $("#fm").form('serializeObject');

    // 获取菜单IDs并包含所有父节点
    let menuIds = $comboTree.combotree('getValues');
    // 处理之前确保menuIds不是null或undefined
    if (menuIds && menuIds.length > 0) {
        // 获取树控件实例
        let tree = $comboTree.combotree('tree');
        let allSelectedIds = [];

        // 遍历选中的ID
        for (let i = 0; i < menuIds.length; i++) {
            let nodeId = menuIds[i];
            // 确保节点ID是字符串类型，以便于比较
            nodeId = String(nodeId);

            // 将当前节点ID添加到结果集，先检查是否已存在
            if (allSelectedIds.indexOf(nodeId) === -1) {
                allSelectedIds.push(nodeId);
                console.log("添加节点ID: " + nodeId);
            } else {
                console.log("节点ID已存在，跳过: " + nodeId);
            }

            // 获取当前节点的所有父节点
            let node = tree.tree('find', nodeId);
            if (node) {
                // 递归获取所有父节点
                getParentNodeIds(tree, node, allSelectedIds);
            }
        }

        // 使用包含所有父节点的ID集合替换原来的选值
        formData.menusId = allSelectedIds;

        // 调试信息
        console.log("提交的菜单ID：", allSelectedIds);
    } else {
        // 确保传递空数组而不是null或undefined
        formData.menusId = [];
        console.log("未选择任何菜单");
    }

    // 获取权限IDs
    let permissionsIds = $('#permissionsCombo').combotree('getValues');
    // 过滤掉模块节点ID（以module_开头的ID）
    permissionsIds = permissionsIds.filter(function(id) {
        return !String(id).startsWith('module_');
    });
    // 添加到表单数据中
    formData.permissionsIds = permissionsIds;

    // 输出完整表单数据到控制台，用于调试
    console.log("提交的完整表单数据：", formData);

    $.ajax({
        url: url,  // 提交的URL
        data: JSON.stringify(formData),
        type: 'post',
        contentType: 'application/json',
        success(data) {
            // 添加调试信息
            console.log("服务器响应：", data);

            $.messager.show({
                title: '提示',
                msg: data.msg,
                timeout: 3000, // 自动关闭时间，单位毫秒
                showType: 'slide' // 显示动画类型，如 'slide', 'fade', 'show'
            });
            if (data.code == '200') {
                // 提交成功后，清除Shiro权限缓存
                clearPermissionCache();

                $('#dlg').dialog('close');
                $datagrid.datagrid('reload');
            }
        },
        error(err) {
            // 添加错误详情
            console.error("保存失败，错误详情：", err);
            $.messager.alert('错误', "保存失败: " + (err.responseJSON ? err.responseJSON.msg : "未知错误"), 'error');
        },
        dataType: 'json'
    })
}

// 递归获取所有父节点ID
function getParentNodeIds(tree, node, idArray) {
    // 获取父节点
    let parent = tree.tree('getParent', node.target);
    if (parent) {
        // 确保父节点ID是字符串类型，以便于比较
        let parentId = String(parent.id);

        // 如果父节点ID不在数组中，则添加
        if (idArray.indexOf(parentId) === -1) {
            idArray.push(parentId);
            console.log("添加父节点ID: " + parentId);
        } else {
            console.log("父节点ID已存在，跳过: " + parentId);
        }

        // 递归处理父节点的父节点
        getParentNodeIds(tree, parent, idArray);
    }
}

// 清除权限缓存
function clearPermissionCache() {
    $.ajax({
        url: 'shiro/clearCache',
        type: 'get',
        success: function(data) {
            console.log('权限缓存已清除');
        },
        error: function() {
            console.error('清除权限缓存失败');
        }
    });
}

// 删除记录
function destroyUser() {
    let row = $datagrid.datagrid('getSelected');
    if (row) {
        $.messager.confirm('确认', '你确定要删除这条记录吗？', function (r) {
            if (r) {
                $.post('roles/delete', {id: row.id}, function (result) {
                    if (result.code == '200') {
                        $datagrid.datagrid('reload'); // 刷新数据表格
                    } else {
                        $.messager.show({
                            title: '错误',
                            msg: result.msg
                        });
                    }
                }, 'json');
            }
        });
    } else {
        $.messager.alert('提示', '请先选择要删除的记录！', 'info');
    }
}

// 没有选中时 || 中多条数据时, 禁用哪些按钮
function disable() {
    $('#editBtn').linkbutton('disable');
    $('#removeBtn').linkbutton('disable');
    $('#detailBtn').linkbutton('disable');
}

// 选中一条数据时启用哪些按钮
function enable() {
    $('#editBtn').linkbutton('enable');
    $('#removeBtn').linkbutton('enable');
    $('#detailBtn').linkbutton('enable');
}

function reload() {
    // 刷新
    $datagrid.datagrid('reload');
}
</script>
</body>
</html>
